home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / MOS / MODCTRL.D < prev    next >
Encoding:
Modula Definition  |  1990-12-12  |  9.2 KB  |  210 lines

  1. DEFINITION MODULE ModCtrl;
  2.  
  3. (*
  4.  * Funktionen des Loadtime-Link-Systems.
  5.  *  - Resident-Machen von Modulen
  6.  *  - Informationen über Namen und Adressen von res. Modulen und Prozeduren.
  7.  *  - Starten von Prozeduren als GEMDOS-Prozeß.
  8.  *)
  9.  
  10. FROM SYSTEM IMPORT LONGWORD, ADDRESS;
  11.  
  12. FROM MOSGlobals IMPORT MemArea;
  13.  
  14.  
  15. PROCEDURE InstallModule (removalInfo: PROC; wsp: MemArea);
  16.   (*
  17.    * Das Modul, von dem aus diese Funktion aufgerufen wird, wird
  18.    * resident gemacht. D.h., daß das Modul, und alle von ihm impor-
  19.    * tierten Module, im Speicher verbleiben, auch wenn sie beendet werden.
  20.    *
  21.    * Dies funktioniert auch bei gelinkten Programmen. Somit ist es sehr
  22.    * einfach, hierüber residente Programme, z.B. für den AUTO-Ordner,
  23.    * zu erstellen. Gegenüber der Verwendung der GEMDOS-Funktion 'PtermRes'
  24.    * kann hierbei der belegte Speicher später wieder freigegeben werden.
  25.    *
  26.    * Verwaltet das residente Programm irgendwelche Ressourcen (GEM, Speicher,
  27.    * der über Storage angefordert wird, usw.), müssen statt der normalen
  28.    * Zugriffs-Funktionen (InitGem, ALLOCATE) die zugehörigen Sys-Funktionen
  29.    * verwendet werden (SysInitGem, SysAlloc)!
  30.    *
  31.    * Ist das Modul, das diesen Aufruf macht, nicht in einem Programm fest
  32.    * eingelinkt, sondern vom Loader (CallModule) gestartet worden, ist
  33.    * es möglich, daß ohne seine Kontrolle das Grundprogramm, z.B. die Shell,
  34.    * terminiert, sodaß das residente Modul mit freigegeben werden muß.
  35.    * Wird ein Modul also vom Loader dynamisch geladen, kann es nur solange
  36.    * resident bleiben, wie seine Basis, also das Programm, was ihn gestartet
  37.    * hat, im Speicher bleibt.
  38.    *
  39.    * Terminiert also das Basisprogramm, wird das Modul, das InstallModule
  40.    * aufrief, über die 'removalInfo'-Routine darüber informiert ('wsp',
  41.    * der den Stack für diesen Aufruf definiert, kann in der Regel leer
  42.    * sein, dh., 'wsp.bottom' ist NIL zuzuweisen). Die angegebene Prozedur
  43.    * muß dann dafür sorgen, daß sie alle Sys-Ressourcen wieder schließt,
  44.    * damit danach das Basisprogramm ordentlich terminieren kann!
  45.    *
  46.    * Ist das Modul, das InstallModule aufruft, Teil eines gelinkten
  47.    * Programms, bleibt solange im Speicher, wie es will - in diesem
  48.    * Fall gibt es keine Möglichkeit von außen, es ohne seine Einwilligung
  49.    * freizugeben (das kann es dann nur selbst mit 'ReleaseModule' erreichen).
  50.    *
  51.    * In den Ordnern des Megamax-Systems befinden sich mehrere Programme,
  52.    * die diese Funktion anschaulich machen:
  53.    *   KbdTest.M  (kurzes Demo-Programm im Ordner DEMO)
  54.    *   ExcDemo.M  (kurzes Demo-Programm im Ordner DEMO)
  55.    *   ModLoad.M  (aufwendiges Hilfs-Programm im Ordner UTILITY)
  56.    *)
  57.  
  58. PROCEDURE ReleaseModule;
  59.   (*
  60.    * Gibt installiertes Modul wieder frei.
  61.    *
  62.    * Noch geöffnete Resourcen (z.B. Speicher, der mit SysAlloc angefordert
  63.    * wurde) müssen vom Programm selbstständig wieder freigegeben (hier z.B.
  64.    * DEALLOCATE) werden!
  65.    *
  66.    * Wird diese Funktion von einem gelinkten Programm aufgerufen, wird
  67.    * dabei auch der eigene Speicher des Programms sofort freigegeben.
  68.    * Nach der Rückkehr aus dieser Funktion läuft das Programm eigentlich
  69.    * dann nicht mehr in reserviertem, geschütztem Speicher - deshalb sollten
  70.    * die Routinen des Programms auch danach nicht mehr aufgerufen werden -
  71.    * lediglich der Rücksprung dorthin, von wo aus zum Programmteil gesprungen
  72.    * wurde, der diesen ReleaseModule-Aufruf tätigte (z.B. durch eine
  73.    * Interrupt-Routine, die auf das Drücken einer bestimmten Tastenkombi-
  74.    * nation zum Freigeben dieses Programms wartete), ist noch sicher.
  75.    *)
  76.  
  77. PROCEDURE FirstModuleStart (): BOOLEAN;
  78.   (*
  79.    * Liefert TRUE, wenn das Modul, das diese Funktion aufruft,
  80.    * installiert ist und zum ersten Mal gestartet wird.
  81.    *)
  82.  
  83.  
  84. TYPE    ModQueryProc= PROCEDURE ( REF (* modName:   *) ARRAY OF CHAR,
  85.                                       (* modAddr:   *) ADDRESS,
  86.                                       (* modLen:    *) LONGCARD,
  87.                                       (* varAddr:   *) ADDRESS,
  88.                                       (* varLen:    *) LONGCARD,
  89.                                   REF (* fileName:  *) ARRAY OF CHAR,
  90.                                       (* module:    *) BOOLEAN,
  91.                                       (* loaded:    *) BOOLEAN,
  92.                                       (* resident:  *) BOOLEAN );
  93.  
  94. TYPE   ProcQueryProc= PROCEDURE ( REF (* procName: *) ARRAY OF CHAR,
  95.                                       (* procAddr: *) ADDRESS );
  96.  
  97. (*$H+  erlaubt die Übergabe von lokalen Prozeduren bei den Query-Funktionen *)
  98.  
  99. PROCEDURE ModQuery (call: ModQueryProc);
  100.   (*
  101.    * Ruft 'call' wiederholt für alle z.Zt. im System vorhandenen Module auf.
  102.    * Damit lassen sich residenten Module anzeigen.
  103.    * Ein Beispiel zeigt das UTILITY-Modul "ModList".
  104.    *)
  105.  
  106. PROCEDURE QueryImports (REF client: ARRAY OF CHAR; call: ModQueryProc);
  107.   (*
  108.    * Ruft 'call' für alle Importe des residenten Moduls 'client' auf.
  109.    * Ein Beispiel zeigt das UTILITY-Modul "ShowImports".
  110.    *)
  111.  
  112. PROCEDURE ProcQuery (REF modName: ARRAY OF CHAR;
  113.                          call   : ProcQueryProc;
  114.                      VAR ok     : BOOLEAN);
  115.   (*
  116.    * Ruft 'call' wiederholt für alle globalen Prozeduren des angegebenen
  117.    * Moduls auf.
  118.    * Damit lassen sich alle Prozeduren eines residenten Moduls anzeigen.
  119.    *
  120.    * Liefert 'ok' FALSE, dann ist das Modul entweder nicht vorhanden oder
  121.    * das Modul enthält keine Prozedurnamen (wg. optimiertem Linken oder
  122.    * Verwendung der Direktive $M-). Zur Unterscheidung kann mit "GetProcAddr"
  123.    * ermittelt werden, ob das Modul resident ist.
  124.    *
  125.    * Ein Beispiel zeigt das UTILITY-Modul "ProcList".
  126.    *)
  127.  
  128. (*$H-*)
  129.  
  130. PROCEDURE GetModName (     addr    : ADDRESS;
  131.                        VAR modName : ARRAY OF CHAR;
  132.                        VAR relAddr : LONGCARD;
  133.                        VAR procName: ARRAY OF CHAR );
  134.   (*
  135.    * Ermittelt anhand der Adresse in 'addr', in welchem Modul diese
  136.    * Adresse liegt und gibt den Modulnamen in 'modName' zurück.
  137.    * Existiert kein Modul an der angegebenen Adresse, wird ein Leer-
  138.    * string in 'modName' geliefert.
  139.    * Ausserdem wird die relative Adresse innerhalb des Moduls in
  140.    * 'relAddr' zurückgegeben (relativ zum Code-Beginn).
  141.    * Wenn das Modul eine Prozedur-Namenstabelle (s. M-Direktive)
  142.    * enthält, wird in 'procName' der Name der zugehörigen Prozedur
  143.    * geliefert, ansonsten ist 'procName' ein Leerstring.
  144.    *)
  145.  
  146. PROCEDURE GetOwnName (VAR codeName: ARRAY OF CHAR);
  147.   (*
  148.    * Liefert Modulnamen des Moduls, von dem diese Funktion aufgerufen wird.
  149.    *
  150.    * Zur Ermittelung der eigenen rel. Position und des akt. Prozedurnamens
  151.    * siehe die Funktion 'GetScanAddr' im Modul 'SysCtrl'.
  152.    *)
  153.  
  154. PROCEDURE GetSourceName ( REF codeName  : ARRAY OF CHAR;
  155.                           VAR sourceName: ARRAY OF CHAR;
  156.                           VAR codeOpts  : LONGWORD      );
  157.   (*
  158.    * Liefert den Quelltextnamen des Moduls 'codeName', falls dieses Modul
  159.    * sich z.Zt. eingelinkt (resident) im Speicher befindet.
  160.    * Zusätzlich werden die Optionen mitgeteilt, mit denen das Modul
  161.    * compiliert wurde (diese Information ist lediglich f. den Scan-Modus
  162.    * des Compilers interessant).
  163.    *)
  164.  
  165. PROCEDURE GetProcAddr (name: ARRAY OF CHAR; VAR location: ADDRESS);
  166.   (*
  167.    * Sucht nach einem Modul-/Prozedurnamen in den eingelinkten Modulen
  168.    * und liefert in 'location' dessen Adresse im Speicher.
  169.    * Wird sie nicht gefunden, wird NIL geliefert. Das kann u.A. daran
  170.    * liegen, daß das betroffene Modul mit der $M- Option compiliert
  171.    * wurde, weshalb keine Prozedurnamen vorhanden sind.
  172.    * Die Startadresse des Modul selbst läßt sich durch alleinige
  173.    * Angabe des Modulnamen ermitteln, Prozedurnamen müssen immer
  174.    * durch ihren Modulnamen und einen Punkt zur Trennung angeführt
  175.    * werden.
  176.    * Um die Adresse des Modulkörpers zu erhalten, muß als Prozedurname
  177.    * wiederum der Modulname angegeben werden.
  178.    * Die Groß-/Kleinschreibung der Namen ist unrelevant.
  179.    * Beispiele:
  180.    *   'Runtime'          liefert Adresse des Runtime-Moduls
  181.    *   'runtime.cap'      liefert Adresse der CAP-Funktion
  182.    *   'mshell.mshell'    liefert Adresse des Initialisierungsteils der Shell
  183.    *)
  184.  
  185.  
  186. PROCEDURE CallProcess (    procedure: PROC;
  187.                            workSpace: MemArea;
  188.                        VAR executed : BOOLEAN;
  189.                        VAR exitCode : INTEGER );
  190.   (*
  191.    * Startet eine Prozedur als Prozeß.
  192.    * 'workSpace' bestimmt den Stack für den Prozeß.
  193.    * Von dieser Funktion zusätzlich wird ca. 260 - 500 Bytes Speicher
  194.    * angefordert.
  195.    * 'executed' liefert FALSE, wenn der Prozeß nicht gestartet werden konnte
  196.    * (z.B. wegen Speichermangel) - In diesem Fall ist 'exitCode' undefiniert.
  197.    *
  198.    * Für diesen neuen Prozeß werden alle Resourcen neu verwaltet (Speicher,
  199.    * GEM-Fenster, usw.). Es werden dazu, ebenso, wie beim Start eines Pro-
  200.    * gramms mittels 'CallModule', die Envelope-/Termination/Removal-Funktionen
  201.    * intern aufgerufen.
  202.    *
  203.    * Achtung: Aufgrund interner Begebenheiten ist es z.Zt. nicht erlaubt,
  204.    *   in solchen als Prozeß gestarteten Prozeduren die Funktion
  205.    *   'InstallModule' aufzurufen - dies kann zu undefinierten Resultaten
  206.    *   führen.
  207.    *)
  208.  
  209. END ModCtrl.
  210.